<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        /* 
            json 深拷贝  
            缺点: 忽略 function  undefined  map set
        */

        //递归深拷贝
        // var obj1 = {
        //     name: "张三",
        //     age: 20
        // }
        // console.log(obj1); //{name: '张三', age: 20}

        // //obj1 地址给了obj2
        // var obj2 = obj1;
        // console.log(obj2); //{name: '张三', age: 20}
        // //重新定义obj2 覆盖原变量,开辟新空间,内容为空
        // var obj2 = {};
        // console.log(obj2); //{}

        // /* 可以将obj1的内容遍历添加到obj2中 
        //     对象数据遍历使用   for in
        // */
        // for (var key in obj1) {

        //     console.log(key, obj1[key]); // name 张三  age 20

        //     //把obj1里的键名和键值加入到obj2里
        //     obj2[key] = obj1[key];
        // }
        // console.log(obj2); //{name: '张三', age: 20}

        // //修改obj2的age值
        // obj2.age = 40;
        // console.log(obj2); //{name: '张三', age: 40}
        // //并不会改变obj1的值  地址不同
        // console.log(obj1); // {name: '张三', age: 20}



        //简单版本的深拷贝函数
        // var obj = {
        //     名字: "张三",
        //     年龄: 20
        // }
        // console.log(obj.年龄);

        // function deepCopy(obj1) {
        //     var obj2 = {};
        //     for (var key in obj1) {
        //         console.log(key, obj1[key]);
        //         //把obj1里的键名和键值加入到obj2里
        //         obj2[key] = obj1[key];
        //     }
        //     //obj2返回出去
        //     return obj2;
        // }
        // var obj1 = {
        //     name: "张三",
        //     age: 20
        // }
        // //obj1的内容给了obj2
        // var obj2 = deepCopy(obj1);
        // console.log(obj2); // {name: '张三', age: 20}
        // //改变obj2地址中的age属性的值
        // obj2.age = 30;
        // //obj2的值有修改
        // console.log(obj2); // {name: '张三', age: 30}
        // //obj1和obj2地址不同   不会被改变
        // console.log(obj1); // {name: '张三', age: 20}



        /* 扩充深拷贝 之 数组 */

        // function deepCopy(obj1) {
        //     // var obj2={};
        //     // var obj2=[];
        //     /* 数组也是对象   需要根据传入的数据自动确定要生成数组还是对象 */
        //     var obj2 = Object.prototype.toString.call(obj1) === "[object Array]" ? [] : {};
        //     for (var key in obj1) {
        //         //把obj1里的键名和键值加入到obj2里
        //         obj2[key] = obj1[key]
        //     }
        //     return obj2;
        // }
        // var obj = {
        //     name: "张三",
        //     age: 20
        // };
        // var newarr = deepCopy(obj);
        // console.log(newarr); // {name: '张三', age: 20}




        /* 
        判断数据类型:
            typeof  判断基本数据类型准确,引用数据类型不准确(检测结果只有object 和 function)
            instanceof 判断某个实例 和构造器 在原型链上是否有关系
            Array.isArray  是否为数组
            Object.prototype.toString.call()   es5 精确判断数据类型
         */
        // var arr = [];
        // var obj = {};
        // console.log(typeof arr); //object
        // console.log(typeof obj); //object


        // console.log(arr instanceof Array); //true
        // console.log(arr instanceof Object); //true
        // console.log(obj instanceof Object); //true


        // var arr = [];
        // var obj = {};
        // var reg = /a/;
        // var n = null;
        // var u = undefined;
        // var b = true;
        // var fn = function () {};

        // console.log(Object.prototype.toString.call(arr)); // [object Array]
        // console.log(Object.prototype.toString.call(obj)); //[object Object]
        // console.log(Object.prototype.toString.call(reg)); //[object RegExp]
        // console.log(Object.prototype.toString.call(n)); //[object Null]
        // console.log(Object.prototype.toString.call(u)); //[object Undefined]
        // console.log(Object.prototype.toString.call(b)); //[object Boolean]
        // console.log(Object.prototype.toString.call(fn)); //[object Function]

        //多层数据及对象的问题
        var obj = {
            name: "张三",
            hobby: {
                name1: "篮球",
                name2: "足球"
            }
        }

        function deepCopy(obj1) {
            //根据传入的数据自动生成数组或者对象
            var obj2 = Object.prototype.toString.call(obj1) === "[object Array]" ? [] : {};
            for (var key in obj1) {
                //把obj1里的键名和键值加入到obj2里
                obj2[key] = obj1[key];
            }
            //返回obj2
            return obj2;
        }
        //调用函数  接收obj2
        var obj2 = deepCopy(obj);
        //改变obj2hobby属性的值
        obj2.hobby.name1 = "乒乓球";
        console.log(obj2); /* hobby: {name1: '乒乓球', name2: '足球'},name: "张三" */
        console.log(obj); /* hobby: {name1: '乒乓球', name2: '足球'},name: "张三" */
    </script>
</body>

</html>